/*
* @Author: obsidian
* @Date:   2016-03-01 09:19:32
* @Last Modified by:   obsidian
* @Last Modified time: 2016-04-21 21:56:50
*/


#include "lcd.h"
#include "lcd_driver.h"
#include "lcd_global.h"
#include "numstr.h"
#include "control/car.h"

void save(void);
void send(void){}

void lcd_init()
{
    //lcd.p_status->p_current = &pid_n; //
    UART3_init(115200);
    lcd_timer_cfg();
    root_n.init(0);
    // LCD_Clear();
    show_menu();
	TIM_Cmd(TIM6, ENABLE);
}

void root_init(void *parg)
{
    char i = 0;
    for(i = 0;i < MAX_ITEM_NUM;i ++)
    {
        if(root_i[i].ctx[0] == 0){break;}
        root_i[i].id = i + 1;
        root_i[i].ctx_len = getstrlen(root_i[i].ctx);
        root_n.itemnum ++;
    }
    root_n.page_num = root_n.itemnum / PAGE_SIZE;
    for(i = 0;i < MAX_CHILD_NUM; i ++)
    {
        if(root_n.child[i] == 0){break;}
        root_n.child[i]->node_id = i;
        root_n.p_item[i].id = i + 1;
        if(root_n.child[i]->init != 0)
        {root_n.child[i]->init(0);}
    }
}

void LCD_Clear(void)
{ 
    TFT_Clear();
    //TFT_Clear();
	//char a = car.version;
	unsigned char a = 0;
	a = car.version + ' ';
    LCD_ShowString(12, 1, " EDC in 2016 ", WHITE,1);
	//LCD_ShowString(27, 1, &a, WHITE,1);
}

void show_value(unsigned short tmpid,unsigned short index,struct Node *p_tmp)
{
    unsigned char value_type = 0;
    if(p_tmp->p_item[index].flag == FILE)
    {
        value_type = lcd.p_status->p_current->p_item[index].value_type;
        switch(value_type)
        {
            case FLOAT:
                num.floatvalue = *((float *)(p_tmp->p_item[index].p_value));
                num.float2str_3();
                LCD_ShowString(2 + 18 * ((tmpid) * 2 / PAGE_SIZE) + p_tmp->p_item[index].ctx_len , 3 + LINE_DIS * (((tmpid)) % (PAGE_SIZE / 2)), num.numstr, WHITE,1);
                num.init();
                break;
            case INTEGER:
                num.intvalue = *((signed short *)(p_tmp->p_item[index].p_value));
                num.int2str();
                LCD_ShowString(2 + 18 * ((tmpid) * 2 / PAGE_SIZE) + p_tmp->p_item[index].ctx_len , 3 + LINE_DIS * (((tmpid)) % (PAGE_SIZE / 2)), num.numstr, WHITE,1);
                num.init();
                break;            
            case STRING:
                LCD_ShowString(
                                    2 + 18 * ((tmpid) * 2 / PAGE_SIZE) + p_tmp->p_item[index].ctx_len,
                                    3 + LINE_DIS * (((tmpid)) % (PAGE_SIZE / 2)),
                                    ((unsigned char *)p_tmp->p_item[index].p_str_item->a) + STRINGLEN * (*((unsigned short *)(p_tmp->p_item[index].p_value))), 
                                    WHITE,
                                    1
                                );
               break;
            default:break;
        }
    }
}

void show_menu()
{
    struct Node *p_tmp      = lcd.p_status->p_current;
    unsigned char index     = 0;
    unsigned char tmpid     = 0;

    LCD_Clear();
    for(index = 0; index < PAGE_SIZE && (index < p_tmp->itemnum - p_tmp->page_index * PAGE_SIZE); index ++)
    {
        tmpid = (p_tmp->p_item[index].id - 1) % PAGE_SIZE;
        LCD_ShowString(1 + 18 * ((tmpid) * 2 / PAGE_SIZE) , 3 + LINE_DIS * (((tmpid)) % (PAGE_SIZE / 2)), p_tmp->p_item[index].ctx, WHITE,1);
        show_value(tmpid, index, p_tmp);
    }
}

void menu_show_run()
{
    struct Node *p_tmp = lcd.p_status->p_current;
    unsigned char index = 0;
    unsigned char tmpid = 0;
    for(index = 0; index < PAGE_SIZE && (index < p_tmp->itemnum - p_tmp->page_index * PAGE_SIZE); index ++)
    {
        if(p_tmp->p_item[index].realtime == 0){continue;}
        tmpid = (p_tmp->p_item[index].id - 1) % PAGE_SIZE;
        show_value(tmpid, index, p_tmp);
    }
}

void input(void *parg)
{
    //ili9481_fill(0, 0, 400,240,BLACK);
    TFT_Clear();
    unsigned char value_type = 0;
    value_type = lcd.p_status->p_item->value_type;
    unsigned char i  =  0;


    if(lcd.p_status->p_item->flag == FILE)
    {
        switch(value_type)
        {
            case FLOAT:
                num.floatvalue = *((float *)(lcd.p_status->p_item->p_value));
                num.float2str_6();
                LCD_ShowString(15 , 3 , num.numstr, WHITE,1);
                num.init();
                break;
            case INTEGER:
                num.intvalue = *((signed short *)(lcd.p_status->p_item->p_value));
                num.int2str();
                LCD_ShowString(15, 3, num.numstr, WHITE,1);
                num.init();
                break;
            case STRING:

                for(i = 0;i < lcd.p_status->p_item->p_str_item->len;i ++)
                {
                    LCD_ShowString(25, 3 + 2 * i, 
                                    ((unsigned char *)lcd.p_status->p_item->p_str_item->a) + STRINGLEN * i, 
                                    WHITE,
                                    1
                                );                    
                }
                break;                
        }
    }
    //ili9481_drawrect(30,40,400,230,WHITE,3);
    LCD_ShowString(6, 5, "change", WHITE,1);
    LCD_ShowString(12, 5, " to: ", WHITE,1);
		lcd.p_status->is_input = 1;
}

signed char add_to_watch(unsigned char* p_str, unsigned char is_int, void* p_value)
{
    // unsigned char i = 0;
    // struct Item * p_item = &run_n.p_item[run_n.itemnum];
    // if(run_n.itemnum == MAX_ITEM_NUM){return 0;}
    // for(i = 0;i < MAX_CHAR_NUM; i ++)
    // {
    //     if(p_str[i] == 0){break;}
    //     p_item->ctx[i] = p_str[i];
    //     p_item->ctx_len ++;
    // }
    // p_item->flag = FILE;
    // p_item->id = run_n.itemnum + 1;
    // p_item->is_int = is_int;
    // p_item->p_value = p_value;
    // run_n.itemnum ++;
    // run_n.page_num = run_n.itemnum / PAGE_SIZE;
    // return 1;
}

void key_process(char key)
{
    unsigned char value_type = 0;
    if(lcd.p_status->is_input == 1)
    {
        if(key == 0x12)//enter
        {
            value_type = lcd.p_status->p_item->value_type;
            if(lcd.p_status->p_item->flag == FILE)
            {
                if(value_type == INTEGER)
                {
                    num.str2int();
                    if(lcd.p_status->p_item->limit[1] > lcd.p_status->p_item->limit[0])
                    {
                        if(num.intvalue < lcd.p_status->p_item->limit[0]){num.intvalue = lcd.p_status->p_item->limit[0];}
                        if(num.intvalue > lcd.p_status->p_item->limit[1]){num.intvalue = lcd.p_status->p_item->limit[1];}
                    }
                    *((signed short *)(lcd.p_status->p_item->p_value)) = num.intvalue;
                    num.init();
                }
                else if(value_type == STRING)
                {

                    num.str2int();
                    if(lcd.p_status->p_item->limit[1] > lcd.p_status->p_item->limit[0])
                    {
                        if(num.intvalue < lcd.p_status->p_item->limit[0]){num.intvalue = lcd.p_status->p_item->limit[0];}
                        if(num.intvalue > lcd.p_status->p_item->limit[1]){num.intvalue = lcd.p_status->p_item->limit[1];}
                    }
                    if(0 < num.intvalue && num.intvalue < lcd.p_status->p_item->p_str_item->len + 1)
                    {           
                        *((signed short *)(lcd.p_status->p_item->p_value)) = num.intvalue - 1;
                    }
                    num.init();
                }
                else
                {

                    num.str2float();
                    if(lcd.p_status->p_item->limit[1] > lcd.p_status->p_item->limit[0])
                    {
                        if(num.floatvalue < lcd.p_status->p_item->limit[0]){num.floatvalue = lcd.p_status->p_item->limit[0];}
                        if(num.floatvalue > lcd.p_status->p_item->limit[1]){num.floatvalue = lcd.p_status->p_item->limit[1];}
                    }
                    *((float *)(lcd.p_status->p_item->p_value)) = num.floatvalue;
                    num.init();              
                }
            }
            lcd.p_status->p_item->func_input_callback(0);

            lcd.p_status->is_input = 0;
            show_menu();
            num.init();
        }
        else if(key == 0x0c) //back
        {
            lcd.p_status->p_item->func_back(0);
            lcd.p_status->is_input = 0;
            num.init(); 
            show_menu();
        }
        else if((key >= 0 && key <= 9) || key == 0xa || key == 0x0b)
        {
            num.input(key);
            num.show(4);
        }
    }
    else 
    {
        if(key == 0x11){save();}
        else if(key == 0x0c) //back
        {
            unsigned char s = lcd.p_status->p_current->node_id;
            lcd.p_status->p_current = lcd.p_status->p_current->parent;
            //lcd.p_status->p_item->func_back(0);
            lcd.p_status->p_item = lcd.p_status->p_current->p_item;
            if(s >= 1) {lcd.p_status->p_item[s - 1].func_back(0);}
            show_menu();
        }
        else if(key == 0xb) //->
        {
            if(lcd.p_status->p_current->page_index + 1 <= lcd.p_status->p_current->page_num)
            {
                lcd.p_status->p_current->page_index++;
                lcd.p_status->p_current->p_item += PAGE_SIZE;
                show_menu();               
            }
        }
        else if(key == 0xa)//<-
        {
            if(lcd.p_status->p_current->page_index + 1 > 1)
            {
                lcd.p_status->p_current->page_index --;
                lcd.p_status->p_current->p_item -= PAGE_SIZE;
                show_menu();          
            }
        }
        else if(key >= 1 && key < lcd.p_status->p_current->itemnum + 1 && (key - 1 < lcd.p_status->p_current->itemnum - lcd.p_status->p_current->page_index * PAGE_SIZE))
        {
            
            if(lcd.p_status->p_current->p_item[key - 1].flag == FOLDER)
            {
                lcd.p_status->p_current->p_item[key - 1].func_enter(0);
                lcd.p_status->p_current = lcd.p_status->p_current->child[key - 1];
                lcd.p_status->p_item = lcd.p_status->p_current->p_item;
                show_menu();           
            }
            else if(lcd.p_status->p_current->p_item[key - 1].flag == FILE)
            {
                lcd.p_status->p_item = &lcd.p_status->p_current->p_item[key - 1];
                lcd.p_status->p_current->p_item[key - 1].func_exec(0);
                num.init();
            }
        }
    }
}
void save()
{
//     unsigned char k = 0;
//     for(k = 1;k < MAX_CHILD_NUM;k ++)
//     {
//         if(root_n.child[k] == 0){break;}
//         if(root_n.child[k]->save != 0x00)
//         {
//             root_n.child[k]->save();
//         }
//     }
}
